/* 
  学习目标：实现修改文章
*/
import React, { useEffect, useRef, useState } from 'react';
import { Breadcrumb, Card, Form, Input, Radio, Button, Upload, message, Modal, Space } from 'antd';
import { Link } from 'react-router-dom';
import Channel from 'components/Channel';

import ReactQuill from 'react-quill';
import 'react-quill/dist/quill.snow.css';

import styles from './index.module.scss';

import { UploadOutlined } from '@ant-design/icons';
import { baseURL } from 'utils/request';
import { getToken } from 'utils/storage';
import { addArticleAPI, getArticleByIdAPI, updateArticleAPI } from 'api/article';

function getIsShowAddIcon(coverType, fileList) {
  if (coverType === 0) {
    return false;
  }

  if (coverType === 1 && fileList.length > 0) {
    return false;
  }

  if (coverType === 3 && fileList.lenth === 3) {
    return false;
  }

  return true;
}

export default function ArticlePublish(props) {
  const [fileList, setFileList] = useState([]);

  const [coverType, setCoverType] = useState(1);

  const handleCoverTypeChange = (type) => {
    switch (type) {
      case 0:
        setFileList([]);
        break;
      case 1:
        setFileList(fileList.slice(0, 1));
        break;
      default:
        setFileList(fileList.slice(0, 3));
        break;
    }
    setCoverType(type);
  };

  const draftRef = useRef(false);
  const articleId = props.match.params.id;

  const handleSubmit = async (values) => {
    if (coverType !== fileList.length) {
      message.warning('图片数量不正确，请检查');
      return;
    }

    // 2. 调整url取出方式
    const images = fileList.map((item) => item.url || item.response.data.url);
    const formData = {
      ...values,
      cover: {
        type: values.coverType,
        images,
      },
    };
    delete formData.coverType; // 命名时尽量和后台字段保持一致，可减少这一步
    delete formData.images; //

    // 3. 根据id判断调用新增，还是编辑接口
    if (articleId) {
      // 1. 封装编辑方法
      await updateArticleAPI({ ...formData, id: articleId }, draftRef.current);
      message.success('文章修改成功', 1);
    } else {
      await addArticleAPI(formData, draftRef.current);
      message.success('文章发表成功', 1);
    }

    props.history.push('/list');
  };

  const upLoadProps = {
    // 接受上传的文件类型，选择时只展示 .png,.jpg,.jpeg
    accept: '.png,.jpg,.jpeg',
    // 由后台接口决定的上传文件类型
    name: 'image',
    // 上传的接口地址
    action: `${baseURL}/v1_0/upload`,
    // 请求头
    headers: {
      Authorization: `Bearer ${getToken()}`,
    },
    // 上传会触发的钩子函数：上传中、上传完成、上传失败
    onChange({ file, fileList }) {
      // 这里不能放到为done中？
      setFileList([...fileList]);

      if (file.status === 'done') {
        message.success(`${file.name} 图片上传成功`);
      } else if (file.status === 'error') {
        message.error(`${file.name} 图片上传失败`);
      }
    },
    onPreview(file) {
      setPreImage(file.thumbUrl || file.url);
    },
    beforeUpload(file) {
      const isAllowType = ['image/png', 'imag/jpg', 'image/jpeg'].includes(file.type);
      if (!isAllowType) {
        message.warning('不允许上传的文件类型');
        // 👍 返回 Upload.LIST_IGNORE，不在其前端显示，不发请求
        // 返回false不发请求，仍在前端显示。
        return Upload.LIST_IGNORE;
      }
      return true;
    },
  };

  const [preImage, setPreImage] = useState('');

  const showAddIcon = getIsShowAddIcon(coverType, fileList);

  const formRef = useRef(null);
  const loadDataById = async (id) => {
    const { data } = await getArticleByIdAPI(id);
    formRef.current.setFieldsValue({
      ...data,
      coverType: data.cover.type,
    });

    setCoverType(data.cover.type);
    // 💥注意：上传组件，需要接收url与uid属性组成的数组, url显示缩略图，uid为标识唯一
    setFileList(data.cover.images.map((url, index) => ({ url, uid: index })));
  };

  useEffect(() => {
    loadDataById(articleId);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  return (
    <div className={styles.publish}>
      <Card
        title={
          <Breadcrumb>
            <Breadcrumb.Item>
              <Link to="/home">首页</Link>
            </Breadcrumb.Item>
            <Breadcrumb.Item>{articleId ? '编辑' : '发布'}文章</Breadcrumb.Item>
          </Breadcrumb>
        }
      >
        <Form
          ref={formRef}
          initialValues={{
            title: '',
            channel_id: 0,
            content: '',
            coverType,
          }}
          size="large"
          labelCol={{ span: 4 }}
          wrapperCol={{ span: 20 }}
          onFinish={handleSubmit}
        >
          <Form.Item
            label="标题"
            name="title"
            rules={[{ required: true, message: '请输入文章标题' }]}
          >
            <Input placeholder="请输入文章标题" />
          </Form.Item>
          <Form.Item
            label="频道"
            name="channel_id"
            rules={[{ required: true, message: '请输入文章标题' }]}
          >
            <Channel></Channel>
          </Form.Item>
          {/* 💥注意：使用name="content" 需要给content设置初始值 */}
          <Form.Item
            label="内容"
            name="content"
            rules={[
              { required: true, message: '内容不能为空' },
              {
                validator(_, value) {
                  if (value === '<p><br></p>') {
                    return Promise.reject('内容不能为空');
                  }
                  return Promise.resolve('通过');
                },
              },
            ]}
          >
            <ReactQuill theme="snow" placeholder="请输入文章内容..." />
          </Form.Item>
          <Form.Item label="封面" name="coverType">
            <Radio.Group onChange={(e) => handleCoverTypeChange(e.target.value)}>
              <Radio value={1}>单图</Radio>
              <Radio value={3}>三图</Radio>
              <Radio value={0}>无图</Radio>
            </Radio.Group>
          </Form.Item>
          <Form.Item wrapperCol={{ offset: 4, span: 20 }}>
            <Upload listType="picture-card" {...upLoadProps} fileList={fileList}>
              {showAddIcon && <Button icon={<UploadOutlined />}></Button>}
            </Upload>
          </Form.Item>

          <Form.Item wrapperCol={{ offset: 4, span: 20 }}>
            <Space>
              <Button htmlType="submit" type="primary">
                {articleId ? '编辑' : '发布'}文章
              </Button>
              <Button htmlType="submit" onClick={() => (draftRef.current = true)}>
                存草稿
              </Button>
            </Space>
          </Form.Item>
        </Form>
      </Card>
      {/* 不要把Modal放在Upload组件内，会冒泡触发到Upload的点击事件 */}
      <Modal
        title="预览图片"
        visible={!!preImage}
        footer={null}
        centered
        onCancel={() => setPreImage('')}
      >
        <img src={preImage} alt="" style={{ objectFit: 'cover', width: '100%' }} />
      </Modal>
    </div>
  );
}
